package com.lightsh.email;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import android.util.Log;

public class EmailHelper {
	private static final boolean DEBUG = true;
	private static final String TAG = "EmailHelper";
	private static final String ATTACHMENT_PATH = "/sdcard/testEmail/";
	
	/**
	 * 发送邮件
	 * @param mailServer		服务器地址，请使用smtp.xxx.com来表示
	 * @param username		用户名
	 * @param password		密码
	 * @param peerName		对应邮箱
	 * @param subject			主题
	 * @param text					内容
	 * @param files				附件数组，可为空
	 * @return						是否成功
	 */
	public static final boolean sendEmail(String mailServer, final String username, final String password, String peerName, String subject, String text, String[] files){
		Properties props = System.getProperties();
		
		props.put("mail.smtp.host", mailServer);
		Session session = Session.getInstance(props, null);
		
		if(DEBUG){
			session.setDebug(true);
		}
		try{
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress(username));
		    msg.setRecipients(Message.RecipientType.TO,
						InternetAddress.parse(peerName, false));
		    msg.setSubject(subject);
		    // 附件
		    if(files != null && files.length > 0){
		    	MimeMultipart mp = new MimeMultipart();
		    	MimeBodyPart mbpText = new MimeBodyPart();
		    	mbpText.setText(text);
				
				mp.addBodyPart(mbpText);
				
		    	for(String filePath : files){
		    		File file = new File(filePath);
		    		if(file.exists()){
		    			MimeBodyPart mbpFile = new MimeBodyPart();
		    			mbpFile.attachFile(file);
		    			mp.addBodyPart(mbpFile);
		    		}
		    	}
		    	msg.setContent(mp);
		    }else{
		    	msg.setText(text);
		    }		    
		    String mailer = "msgsend";
		    msg.setHeader("X-Mailer", mailer);
		    msg.setSentDate(new Date());
		    
		    Transport transport = session.getTransport("smtp");
		    transport.connect(username, password);
		    transport.sendMessage(msg, msg.getAllRecipients());

		    System.out.println("\nMail was sent successfully.");
		}catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 获取邮件信息
	 * @param protocol    		协议，需要使用imap
	 * @param mailServer		例如: imap.163.com
	 * @param username
	 * @param password
	 */
	public static final void fetchEmail(String protocol, String mailServer, final String username, final String password){
		try{
			Properties props = System.getProperties();
			Session session = Session.getDefaultInstance(props, null);
			Store store = session.getStore(protocol);
			store.connect(mailServer, username, password);	
			Folder folder = store.getFolder("INBOX");
			if(folder != null){
				folder.open(Folder.READ_WRITE);
				if(DEBUG){
					Log.i(TAG, "邮件总数 = " + folder.getMessageCount());
					Log.i(TAG, "新邮件数 = " + folder.getNewMessageCount());
					Log.i(TAG, "未读总数 = " + folder.getUnreadMessageCount());
				}
				if(folder.getNewMessageCount() > 0){
					Message[] msgs = folder.getMessages();
					int count = msgs.length;
					Message msg;	
					for(int i = count - 1; i >= 0; --i){
						msg = msgs[i];
						if(!msg.isSet(Flag.SEEN)){
							if(isTargetEmail(msg)){
								// FIXME 读取对应的手机号
								handleTargetEmail(msg);
								// 目标邮件，标记为已读
								msg.setFlag(Flag.SEEN, true);
							}
						}else{
							// 找到第一封已读邮件旧退出循环
							break;
						}
					}
				}else{
					// 无新邮件
					Log.d(TAG, "no new email");
				}
				folder.close(true);
			}else{
				// 找不到收件箱
				Log.w(TAG, "cant open INBOX");
			}
			Log.d(TAG, "fetch email end");
			store.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private static final void handleTargetEmail(Message msg){
		try{
			InternetAddress[] addrs = (InternetAddress[]) msg.getFrom();
			Log.d(TAG, "handleTargetEmail ... ");
			String from = addrs.length > 0 ? addrs[0].getAddress() : "";
			if(DEBUG){
				Log.d(TAG, from + " : " + msg.getSubject());
			}			
			// 只处理包含附件的邮件
			if(msg.isMimeType("multipart/*")){
				Multipart mult = (Multipart) msg.getContent();
				int count = mult.getCount();
				for(int i = 0; i < count; ++i){
					Part part = mult.getBodyPart(i);
					if(isAttachment(part)){
						saveFile(from, part);
					}
				}				
			}else{
				Log.w(TAG, "targetEmail not multipart !");
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private static final void saveFile(String from, Part part){
		try {
			// FIXME 可以考虑修改文件最后访问时间或者增加文件名标志来记录文件的创建时间
			String fileName = MimeUtility.decodeText(part.getFileName() != null ? part.getFileName() : "");
			if(DEBUG){
				Log.d(TAG, "file name = " + fileName);
				Log.d(TAG, "content type = " + part.getContentType());
				Log.d(TAG, "size = " + part.getSize());
			}
			String rootPath = ATTACHMENT_PATH + getLegalFileName(from) + "/";
			File fileRoot = new File(rootPath);
			if(!fileRoot.exists()){
				fileRoot.mkdirs();
			}
			File file = new File(rootPath + fileName);
			if(!file.exists()){
				file.createNewFile();
			}else{
				Log.w(TAG, "file exist " + fileName);
			}
			InputStream is = null;
			OutputStream os = null;
			byte[] buf = new byte[1024];
			int nRead;
			try{
				is = part.getInputStream();
				os = new FileOutputStream(file);
				while((nRead = is.read(buf)) != -1){
					os.write(buf, 0, nRead);
				}
				os.flush();
				Log.d(TAG, "save file success");
			}finally{
				if(is != null){
					is.close();
				}
				if(os != null){
					os.close();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private static final String getLegalFileName(String from){
		// FIXME 取邮件名的前部分
		int index = from.indexOf("@");
		if(index == -1){
			index = from.indexOf(".");
		}
		if(index == -1){
			return from;
		}else if(index == 0){
			return "error name";
		}else{
			return from.substring(0, index);
		}
		
	}
	
	public static final boolean isAttachment(Part part){
		String disp;
		try {
			disp = part.getDisposition();
			return disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT);
		} catch (MessagingException e) {
			e.printStackTrace();
		}
		return false;
	}
	public static final boolean isTargetEmail(Message msg){
		// FIXME 判断是否目标邮件
		return true;
	}
}
